/*
 **********************************************************************
 * Copyright (c)  2008 - 2022, Shanghai AisinoChip Co.,Ltd .
 * @file        main.c
 * @version     V1.0.0
 * @date        2022
 * @author      Aisinochip Firmware Team
 * @brief       GPIO Test Main File
 **********************************************************************
 */
#include "main.h"
#include "lcd_XJR80260H.h"
#include "GX21M15.h"
#include "ntc.h"
#include "uart.h"

/* 指向信号量的指针 */
static rt_sem_t dynamic_sem = RT_NULL;
rt_sem_t uart_sem = RT_NULL;
rt_sem_t rs485_rx_sem = RT_NULL;
rt_sem_t rs485_tx_sem = RT_NULL;
rt_sem_t zgb_rx_sem = RT_NULL;
rt_sem_t zgb_tx_sem = RT_NULL;
GPIO_InitTypeDef GPIOA_Handle;
GPIO_InitTypeDef GPIOC_Handle;
GPIO_InitTypeDef GPIOD_Handle;
GPIO_InitTypeDef Relay;
extern UART_HandleTypeDef UART3_Handle;
extern WDT_HandleTypeDef WDT_Handle;
int s_index = 1;
int s_index1 = 1;
uint8_t rxBuf[64] = {0};
uint32_t rxLen = 0;
void relay_on();
void relay_off();
uint8_t zgb_TxBuffer[10];
uint8_t zgb_RxBuffer[10];
uint32_t rxlen;
volatile uint32_t gu32_TxCpltStatus = false, gu32_TxCpltStatus2 = false, gu32_TxCpltStatus3 = false;
volatile uint32_t gu32_RxCpltStatus = false, gu32_RxCpltStatus2 = false, gu32_RxCpltStatus3 = false;
/*********************************************************************************
 * Function    : GPIOAB_IRQHandler
 * Description :
 * Input       :
 * Outpu       :
 * Author      : Chris_Kyle                         Date : 2021
 **********************************************************************************/
void GPIOAB_IRQHandler(void)
{
    HAL_GPIO_IRQHandler(GPIOA, GPIO_PIN_4);
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == UART1) // Transfor Data By UART1
    {
        gu32_TxCpltStatus = true;
    }
    else if (huart->Instance == UART2) // Transfor Data By UART2
    {
        gu32_TxCpltStatus2 = true;
    }
    else if (huart->Instance == UART3) // Transfor Data By UART3
    {
        rt_sem_release(rs485_tx_sem);
    }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == UART1) // receive data by UART1
    {
        gu32_RxCpltStatus = true;
    }
    else if (huart->Instance == UART2) // receive data by UART2
    {

        rt_sem_release(zgb_rx_sem);
    }
    else if (huart->Instance == UART3) // receive data by UART3
    {
        rt_sem_release(rs485_rx_sem);
    }
}
void UART3_IRQHandler(void)
{
    HAL_UART_IRQHandler(&UART3_Handle);
}
void UART2_IRQHandler(void)
{
    HAL_UART_IRQHandler(&UART2_Handle);
}
void UART2_RX_DMA_ITC_Callback(void)
{
    rt_sem_release(zgb_rx_sem);
}
/*********************************************************************************
 * Function    : main
 * Description : The application entry point.
 * Input       : None
 * Output      : None
 **********************************************************************************/
int main(void)
{
    float temp = 0.0;
    int data_len = 0;
    uint32_t temp_u32;
    int i = 1;
    char str[32];
    while (1)
    {
        rt_thread_delay(1000);
        gx21m15h_get_temp(&temp);

        // sprintf(str, "temp=%.3f\n", temp);
        // rt_kprintf(str);
        lcd_set_num123(temp);
        lcd_set_num456(temp);
    }
}
ALIGN(RT_ALIGN_SIZE)
static char zgb_thread_stack[256];
static struct rt_thread zgb_thread;

static void zgb_thread_handle(void *parameter)
{
    while (1)
    {
        HAL_UART_Receive_DMA(&UART2_Handle, zgb_RxBuffer, sizeof(zgb_RxBuffer));
        //HAL_UART_Receive_IT(&UART2_Handle, zgb_RxBuffer, sizeof(zgb_RxBuffer), UART_RX_FIFO_1_2);
        rt_sem_take(zgb_rx_sem, RT_WAITING_FOREVER);
        /*start handle zgb recv data, demo code,send recv data*/
        memcpy(zgb_TxBuffer, zgb_RxBuffer, sizeof(zgb_RxBuffer));
        rt_kprintf("zgb_RxBuffer:%p, des:%p\n", zgb_RxBuffer, UART2_Handle.HDMA_Rx->Instance->DEST_ADDR);

        // HAL_UART_Transmit_IT(&UART2_Handle, zgb_TxBuffer, UART2_Handle.lu32_RxCount, UART_TX_FIFO_1_2);
        HAL_UART_Transmit_DMA(&UART2_Handle, zgb_TxBuffer, sizeof(zgb_RxBuffer));
        /*end handle zgb recv data, demo code,send recv data*/
    }
}
ALIGN(RT_ALIGN_SIZE)
static char rs485_thread_stack[256];
static struct rt_thread rs485_thread;
uint8_t rs485_TxBuffer[128];
uint8_t rs485_RxBuffer[128];
int send_485_data(uint8_t *fu8_Data, uint32_t fu32_Size)
{
    rs485_ready_send();//发送485数据，不可删除
    HAL_UART_Transmit(&UART3_Handle, fu8_Data, fu32_Size, 100);
    rs485_ready_rx();
} 
static void rs485_thread_handle(void *parameter)
{
    while (1)
    {
        HAL_UART_Receive_IT(&UART3_Handle, rs485_RxBuffer, sizeof(rs485_RxBuffer), UART_RX_FIFO_1_2);
        rt_sem_take(rs485_rx_sem, RT_WAITING_FOREVER);
        /*start handle 485 recv data, demo code,send recv data*/
        memcpy(rs485_TxBuffer, rs485_RxBuffer, UART3_Handle.lu32_RxCount);
					rt_kprintf("rec count:%d\n", UART3_Handle.lu32_RxCount);
        send_485_data(rs485_TxBuffer, UART3_Handle.lu32_RxCount);
        /*end handle 485 recv data, demo code,send recv data*/
    }
}
ALIGN(RT_ALIGN_SIZE)
static char thread_stack[256];
static struct rt_thread temp_os_thread;
static void temp_os_thread_handle(void *parameter)
{
    static rt_err_t result;
    static rt_uint8_t number = 0;
    GPIOD_Handle.Pin = GPIO_PIN_3;
    GPIOD_Handle.Mode = GPIO_MODE_OUTPUT_PP;
    GPIOD_Handle.Pull = GPIO_PULLUP;
    GPIOD_Handle.Alternate = GPIO_FUNCTION_0;
    HAL_GPIO_Init(GPIOD, &GPIOD_Handle);
    while (1)
    {
        result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
        if (result != RT_EOK)
        {
            rt_kprintf("t2 take a dynamic semaphore, failed.\n");
            rt_sem_delete(dynamic_sem);
            return;
        }
        else
        {
            number++;
            rt_kprintf("t2 take a dynamic semaphore. number = %d\n", number);
        }
    }
}

static void idle_hook(void)
{
    HAL_WDT_Feed(&WDT_Handle);
}
void relay_on()
{
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
}
void relay_off()
{
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_CLEAR);
}
void init_relay_gpio()
{
    Relay.Pin = GPIO_PIN_2;
    Relay.Mode = GPIO_MODE_OUTPUT_PP;
    Relay.Pull = GPIO_PULLUP;
    Relay.Alternate = GPIO_FUNCTION_0;
    HAL_GPIO_Init(GPIOD, &Relay);
}
int thread_init(void)
{
    init_relay_gpio();
    dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
    if (dynamic_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }
    uart_sem = rt_sem_create("uart_sem", 0, RT_IPC_FLAG_PRIO);
    if (uart_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }
    rs485_rx_sem = rt_sem_create("rs485_rx_sem", 0, RT_IPC_FLAG_PRIO);
    if (rs485_rx_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }
    rs485_tx_sem = rt_sem_create("rs485_tx_sem", 0, RT_IPC_FLAG_PRIO);
    if (rs485_tx_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }
    zgb_rx_sem = rt_sem_create("zgb_rx_sem", 0, RT_IPC_FLAG_PRIO);
    if (zgb_rx_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }
    zgb_tx_sem = rt_sem_create("zgb_tx_sem", 0, RT_IPC_FLAG_PRIO);
    if (zgb_tx_sem == RT_NULL)
    {
        rt_kprintf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        rt_kprintf("create done. dynamic semaphore value = 0.\n");
    }

    rt_thread_init(&temp_os_thread,
                   "temp_os_thread",
                   temp_os_thread_handle,
                   RT_NULL,
                   &thread_stack[0],
                   sizeof(thread_stack),
                   10, 5);
    rt_thread_startup(&temp_os_thread);
    rt_thread_init(&rs485_thread,
                   "rs485_thread",
                   rs485_thread_handle,
                   RT_NULL,
                   &rs485_thread_stack[0],
                   sizeof(rs485_thread_stack),
                   10, 5);
    rt_thread_startup(&rs485_thread);
    rt_thread_init(&zgb_thread,
                   "zgb_thread",
                   zgb_thread_handle,
                   RT_NULL,
                   &zgb_thread_stack[0],
                   sizeof(zgb_thread_stack),
                   10, 5);
    rt_thread_startup(&zgb_thread);
    rt_thread_idle_sethook(idle_hook);
    return 0;
}
INIT_APP_EXPORT(thread_init);
